﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using GeneralDFS.BusinessLogical.IO;
using GeneralDFS.DataEntity.IO;
using Directory = System.IO.Directory;
using File = System.IO.File;

namespace GeneralDFS.BusinessLogical
{
    public class FsDir
    {
        public DirectoryInfo CurrentDirectory; //存储数据目录
        public List<FsDir> Children; //目录current的子目录；
        public int NumBlocks; //存储目录当前已经存储的数据块的数量；
        private const int MaxChildrenPerDir = 16;
        private const int MaxBlocksPerDir = 64;
        private const string SubdirName = "subdir";
        private const string PreName = "blk_";

        public FsDir(string path)
        {
            CurrentDirectory = new DirectoryInfo(Path.Combine(path));
            if (!CurrentDirectory.Exists)
                CurrentDirectory.Create();
            if (CurrentDirectory.GetDirectories().Length > 0)
            {
                AddSurDir();
            }
            UpdateBlockNum();
        }

        public void UpdateBlockNum()
        {
            FileInfo[] files = CurrentDirectory.GetFiles("blk_*",SearchOption.TopDirectoryOnly);
            NumBlocks = files.Length;
        }

        public FileStream CreateMetaFile(Guid guid)
        {
            NumBlocks++;
            return File.Create(Path.Combine(CurrentDirectory.FullName, PreName + guid.ToString() + ".meta"));
        }

        public string BlockName(Guid guid)
        {
            return Path.Combine(CurrentDirectory.FullName, PreName + guid.ToString());
        }

        public string MetaName(Guid guid)
        {
            return BlockName(guid) + ".meta";
        }

        /// <summary>
        /// 将临时文件转移到存放文件的地址
        /// </summary>
        /// <param name="sourceFilePath">临时文件的地址</param>
        /// <param name="guid"></param>
        /// <returns>返回文件块的地址</returns>
        public string MoveBlockToCurrentDirectory(string sourceFilePath, Guid guid)
        {
            string filePath = Path.Combine(CurrentDirectory.FullName, PreName + guid.ToString());
            File.Move(sourceFilePath, filePath);
            NumBlocks += 2;
            return filePath;
        }

        public bool Exist(Guid guid)
        {
            return File.Exists(Path.Combine(CurrentDirectory.FullName, PreName + guid.ToString()));
        }

        /// <summary>
        /// 判断文件块数目是否已经达到上限
        /// </summary>
        /// <returns>文件块数量达到上限，返回false，没达到上限返回true</returns>
        public bool IsFree()
        {
            if (NumBlocks < MaxBlocksPerDir)
            {
                return true;
            }
            return false;
        }

        public void AddSurDir()
        {
            if (Children != null && Children.Count == MaxChildrenPerDir)
                return;
            lock (this)
            {
                Children = new List<FsDir>(MaxChildrenPerDir);
                for (int i = 0; i < MaxChildrenPerDir; i++)
                {
                    string ChildrenPath = Path.Combine(CurrentDirectory.FullName, GetChildrenName(i));
                    FsDir fsDir = new FsDir(ChildrenPath);
                    Children.Insert(i, fsDir);
                    //Children.Add(fsDir);
                }
            }
        }

        public static string GetChildrenName(int index)
        {
            if (index > MaxChildrenPerDir || index < 0)
                return null;
            if (index >= 0 && index <= 9)
            {
                return SubdirName + index;
            }
            char c = (char) ('a' + index - 10);
            return string.Format("{0}{1}", SubdirName, c);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="c"></param>
        /// <returns>If c == '-',return -1</returns>
        public static int GetChildrenIndex(char c)
        {
            if (c == '-') return -1;
            if (c >= '0' && c <= '9')
                return c - '0';
            return c - 'a' + 10;
        }

    /*
public void UpdateChildren()
{
    DirectoryInfo[] directory = currentDirectory.GetDirectories(SubdirName, SearchOption.TopDirectoryOnly);
    if (Children != null)
    {
        if (Children.Count!=MaxChildrenPerDir)
        {
            Children.Clear();
            for (int i = 0; i < MaxChildrenPerDir; i++)
            {
                if (Directory.Exists(Path.Combine(currentDirectory.FullName, GetChildrenName(i))))
                {
                    Children.Add(new FSDir(Path.Combine(currentDirectory.FullName, GetChildrenName(i));
                    //Children.Insert(i, new FSDir(Path.Combine(currentDirectory.FullName, GetChildrenName(i))));
                }
            }
        }
        else
        {
            for (int i = 0; i < MaxBlocksPerDir; i++)
            {
                Children[i].UpdateBlockNum();
            }
        }
    }
}
 */
    }
}
